<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 对象限制型方法
    // ES5中提供了一系列限制对象被修改的方法，用来防止被某些对象被无意间修改导致的错误。每种限制类型包含一个判断方法和一个设置方法。

    // 【1】阻止对象扩展
    // Object.preventExtensions()用来限制对象的扩展，设置之后，对象将无法添加新属性，用法如下：
    // Object.preventExtensions(obj);
    // 该方法接收一个要被设置成无法扩展的对象作为参数，需要注意两点：
    // 1、对象的属性不可用扩展，但是已存在的属性可以被删除
    // 2、无法添加新属性指的是无法在自身上添加属性，如果是在对象的原型上，还是可以添加属性的。
    function Person(name) {
        this.name = name;
    }
    var person = new Person("Jack");
    Object.preventExtensions(person);

    delete person.name;
    person.name = 'new name';
    console.log(person.name); //undefined

    Person.prototype.age = 15;
    console.log(person.age); //15
    // 【2】Object.isExtensible()方法用来判断一个对象是否可扩展，默认情况是true
    console.log(Object.isExtensible(person)); //fale;上个案例中，对象扩展被阻止，所以此处返回false。
    // 【3】将对象密封；Object.seal可以密封一个对象并返回被密封的对象。
    // 密封对象无法添加或删除已有属性，也无法修改属性的enumerable，writable，configurable，但是可以修改属性值。
    function Person(name) {
        this.name = name;
    }
    var person1 = new Person("Jack");
    Object.seal(person1);
    delete person1.name;
    console.log(person1.name); //Jack
    // 将对象密封后，使用delete删除对象属性，还是可以访问得到属性。
    // 【4】通过Object.isSealed可以用来判断一个对象是否被密封了。
    console.log(Object.isSealed(person1)); //true
    // 【5】冻结对象
    // Object.freeze方法用来冻结一个对象，被冻结的对象将无法添加，修改，删除属性值，也无法修改属性的特性值，即这个对象无法被修改。该方法返回被冻结的对象。
    function Person5(name) {
        this.name = name;
    }
    var person5 = new Person5("Jack");
    Object.freeze(person5);

    delete person5.name;
    console.log(person5.name); //Jack

    Person5.prototype.age = 15;
    console.log(person5.age); //15
    // 分析上面的代码我们可以发现，被冻结的对象无法删除自身的属性，但是通过其原型对象还是可以新增属性的。
    console.log(Object.isFrozen(person5)); //true
    // 通过Object.isFrozen可以用来判断一个对象是否被冻结了。

    // 可以发现：这三个限制对象的方法的限制程度是依次上升的。
</script>

</html>